
/* <Instruccion> := var <identificador> = <expresion>
	| <identificador> = <expresion>
	| si <expresion> entonces <Instruccion> [sino <Instruccion> ] fin si
	| seleccion <identificador> 
	| para <identificador> = <expresion> hasta <expresion> hacer <Instruccion> siguiente
	| mientras <expresion> hacer <Instruccion> siguiente
	| repetir <instruccion> hasta que <expresion> 
	| leer(<identificador>)
	| escribir(<expresion>)
	| <Instruccion> ; <Instruccion>
  */

public interface Instruccion
{
}

public class DeclaracionClase : Instruccion
{
	public string Identificador;
	public DeclaracionFunciones DeclaracionFunciones;
}

public class DeclaracionFunciones : Instruccion
{
	public DeclaracionFuncion funcion;
	public DeclaracionFunciones funciones;
}

public class DeclaracionFuncion :Instruccion
{
	public string Identificador;
	public Secuencia secuencia;
}

// var <identificador> = <expresion>
public class Declaracion : Instruccion
{
    public string Identificador;
    public Expresion Expresion;
}

// escribir(<expresion>)
public class Escribir : Instruccion
{
    public Expresion Expresion;
}

// <identificador> = <expresion>
public class Asignacion : Instruccion
{
    public string Identificador;
    public Expresion Expresion;
}

// for <ident> = <expr> to <expr> do <stmt> end
public class CicloPara : Instruccion
{
    public string Identificador;
    public Expresion Desde;
    public Expresion Hasta;
    public Instruccion Cuerpo;
}

// read_int <ident>
public class Leer : Instruccion
{
    public string Identificador;
}

// <stmt> ; <stmt>
public class Secuencia : Instruccion
{
    public Instruccion Primero;
    public Instruccion Segundo;
}

/* <expr> := <string>
 *  | <int>
 *  | <arith_expr>
 *  | <ident>
 */
public interface Expresion
{
}

// <string> := " <string_elem>* "
public class LiteralCadena : Expresion
{
	public string Valor;
}

// <int> := <digit>+
public class LiteralEntero : Expresion
{
	public int Valor;
}

public class LiteralReal : Expresion
{
	public double Valor;
}

// <ident> := <char> <ident_rest>*
// <ident_rest> := <char> | <digit>
public class Variable : Expresion
{
	public string Identificador;
}

public class Invocacion : Expresion, Instruccion
{
	public string Identificador;
	public Expresion Expresion;
}

// <bin_expr> := <expr> <bin_op> <expr>
public class ExpresionBinaria : Expresion
{
	public Expresion Izquierda;
	public Expresion Derecha;
	public OperadorBinario Operador;
}

// <bin_op> := + | - | * | /
public enum OperadorBinario
{
	Add,
	Sub,
	Mul,
	Div,
	Mod,
}